package jwlee.testxml;

import javax.script.Bindings;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;

public class JavaScriptParser {

	public static void main(String[] args) throws Exception {
		// 直接解析
		SimpleBindings bindings = new SimpleBindings();
		bindings.put("v1", new Double(10000.1));
		bindings.put("v2", new Double(20000.2));
		String script = " res =  Math.max(v1,v2)+v1";
		Object result1 = parse(script, bindings, null);
		System.out.println(result1);

		// 创建脚本
		String script2 = "function getMax(v3,v4) {return Math.max(v3,v4)+v3}";
		Object result2 = parse(script2, null, "getMax", 10000.1, 20000.2);
		System.out.println(result2);

		String script3 = "function formatNum(val,format){var dw = false;try{var num;if(val=='' || val==null){num='';}else{format = format.replace(/w/g,''); if (dw && (format != '#,##0') && (format.substring(format.length-1) != '%')){format = format + 'w';}if(format.substring(format.length-1)=='w'){val=parseFloat(val)/10000;format = format.substring(0,format.length-1);}num =  formatNumber(val,format);var len = num.length;if(len != 0){if(num.charAt(len - 1) == '.'){num = num.substring(0,len-1);}else if(num.charAt(len - 1) == '%' && num.charAt(len - 2) == '.'){num = num.substring(0,len-2)+'%';}}}return num;}catch(e){return val;}}";
		Object result3 = parse(script3, null, "formatNum", .9959, "#,##0");
		System.out.println(result3);
//		String script3 = "var i = -1;function setBg(){i++;if(i % 2 == 0){return \"tr_bg1\";}else{return \"tr_bg\";}} var obj = this.selectSingleNode(\"//DW_ATTRIBUTE\");var idx = 0;if (obj != null){idx = parseInt(obj.childNodes(1).text,10)*(parseInt(obj.childNodes(3).text,10)-1);}else{idx = 0;} function count(){return ++idx;}  var rowInd = 0; function rowIndex(){return ++rowInd;} function getRowIndex(){return rowInd;} function getRadioName(){return \"rdo_\"+rowInd;}  function formatNoday(nodeName,format){var oNode = this.selectSingleNode(nodeName);if(oNode == null){return \"\";} var val = oNode.text; var varNoday = val.substring(0,4); varNoday += \"-\"; varNoday += val.substring(4,6); return varNoday; } function formatNum(nodeName,format){var dw = false;var oNode = this.selectSingleNode(nodeName);if(oNode == null){return \"\";}var val = oNode.text;try{var num;if(val=='' || val==null){  num='';}else{  format = format.replace(/w/g,'');   if (dw &amp;&amp; (format != '#,##0') &amp;&amp; (format.substring(format.length-1) != '%')){format = format + 'w';}if(format.substring(format.length-1)=='w'){val=parseFloat(val)/10000;format = format.substring(0,format.length-1);}num =  formatNumber(val,format);var len = num.length;if(len != 0){if(num.charAt(len - 1) == '.'){num = num.substring(0,len-1);}else if(num.charAt(len - 1) == '%' &amp;&amp; num.charAt(len - 2) == '.'){num = num.substring(0,len-2)+\"%\";}}}return num;}catch(e){return val;}}function getFontColor(nodeName){var oNode = this.selectSingleNode(nodeName); if(oNode == null){return \"\";}var val = oNode.text; try{var color=\"green\";if(val==1){color=\"red\";}else if(val==-1){color=\"yellow\";}return color;}catch(e){return \"\";}}";
//		Object result3 = parse(script3, null, "setBg", 1);
//		System.out.println(result3);
	}

	public static Object parse(String script, Bindings bindings,
			String funcName, Object... args) throws ScriptException,
			NoSuchMethodException {
		ScriptEngineManager sem = new ScriptEngineManager();
		ScriptEngine engine = sem.getEngineByExtension("js");

		if (bindings != null) {
			engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
		}

		Object obj = engine.eval(script);
		if (funcName == null) {
			return obj;
		}

		Object result = ((Invocable) engine).invokeFunction(funcName, args);
		return result;
	}
}
